package com.ilink.ilinkgateway.jwt;

import cn.hutool.core.exceptions.ValidateException;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.ilink.ilinkcommon.exception.UnauthorizedException;
import com.ilink.ilinkgateway.config.JwtProperties;
import java.util.Date;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class JwtTokenProvider {

    @Autowired
    JwtProperties jwtProperties;

    private String secretKey;
    private Algorithm algorithm;
    private JWTVerifier verifier;


    @PostConstruct
    protected void init() {
        secretKey = jwtProperties.getSecretKey();
        algorithm = Algorithm.HMAC256(secretKey);
        verifier = JWT.require(algorithm).build();
    }

    /**
     * @return java.util.Date
     * @Author LiuZheng
     * @Description 生成token
     * @Date 15:26 2024-09-15
     * @Param [token]
     **/
    public String createToken(Map<String, String> data, long expiresIn) {
        return JWT.create()
            .withSubject(data.get("sub"))
            .withClaim("type", data.get("type"))
            .withExpiresAt(new Date(System.currentTimeMillis() + expiresIn))
            .sign(algorithm);
    }


    /**
     * @return java.util.Date
     * @Author LiuZheng
     * @Description 从token中解析出userId
     * @Date 15:26 2024-09-15
     * @Param [token]
     **/
    public String getUserIdFromToken(String token) {
        try {
            verifier.verify(token);
            DecodedJWT jwt = JWT.decode(token);
            String userId = jwt.getClaim("sub").asString();
            return userId;
        } catch (JWTDecodeException | IllegalArgumentException | UnauthorizedException e) {
            return null;
        }
    }

    /**
     * @return java.util.Date
     * @Author LiuZheng
     * @Description 从token中解析出token类型
     * @Date 15:26 2024-09-15
     * @Param [token]
     **/
    public String getTokenTypeFromToken(String token) {
        try {
            verifier.verify(token);
            DecodedJWT jwt = JWT.decode(token);
            String tokenType = jwt.getClaim("type").asString();
            return tokenType;
        } catch (JWTDecodeException | IllegalArgumentException | UnauthorizedException e) {
            return null;
        }
    }

    /**
     * @return java.util.Date
     * @Author LiuZheng
     * @Description 从token中解析出有效时间
     * @Date 15:26 2024-09-15
     * @Param [token]
     **/
    public Date getExpiresFromToken(String token) {
        try {
            verifier.verify(token);
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getExpiresAt();
        } catch (JWTDecodeException | IllegalArgumentException | ValidateException e) {
            return null;
        }
    }

    /**
     * @return void
     * @Author LiuZheng
     * @Description 对token内容做解析和校验
     * @Date 15:25 2024-09-15
     * @Param [token]
     **/
    public void validateToken(String token) {
        Date expiration = getExpiresFromToken(token);
        if (expiration == null || new Date().after(expiration)) {
            throw new UnauthorizedException("Token has expired.");
        }

        String id = getUserIdFromToken(token);
        String tokenType = getTokenTypeFromToken(token);

        if (id == null || tokenType == null) {
            throw new UnauthorizedException("Invalid token details.");
        }

    }

}
